home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software 2000
/
Software 2000 Volume 1 (Disc 1 of 2).iso
/
utilities
/
u621.dms
/
u621.adf
/
Dmake
/
dmake.doc
< prev
next >
Wrap
Text File
|
1992-04-29
|
11KB
|
386 lines
DMAKE.DOC
RELEASE V1.0 3-Feb-1989
DMake (c)Copyright 1989 by Matthew Dillon, All Rights Reserved
Matthew Dillon
891 Regal Rd.
Berkeley, Ca. 94708
USA
dillon@postgres.berkeley.edu
..!ucbvax!dillon
You MUST be familar with 'make' to understand these instructions.
Please read the bug list at the end.
The default file is 'DMakefile'. Options are:
-a force all time comparisons to fail
-f filename use this instead of DMakefile
-n don't actually execute the lines
-v (debugging, have fun)
-d (debugging, have lots of fun)
-s silent .. don't display startup copyright notice
CONTROL FILE
The control file, DMakefile by default, is made up of macros,
dependancies, and comments. A macro looks like this:
<macroname> = <string>
CFLAGS = +L
A dependancy looks like this: Note that commands may have an
optional '-' in front of them telling DMake to ignore the exit
code.
<left1> <left2> <left3> .. : <right1> <right2> <right3>
[-]<command>
[-]<command>
blank-line
a.o b.o c.o : a.c b.c c.c
cc $(CFLAGS) %(right) -o %(left)
Echo "hi!"
d.o e.o f.o : d.x e.x f.x
...
Any line may be 'continued' onto the next line by specifying a backslash
at the end of the line:
a.o b.o c.o : \
a.c b.c c.c
Echo "ha %(left) %(right)"
# Echo "this line commented out"
Any line my be commented out with a # at the beginning (The hash must
occur at the beginning of a line and will not work in the middle of
a continued line).
# This is a comment
SPECIFICATIONS OF DEPENDANCIES
A dependancy consists of one or more left-hand-sides and zero or more
right-hand-sides. Each element on the left is matched to an associated
element on the right singly. that is:
a.o b.o c.o : a.c b.c c.c
<cmdlist>
Is equivalent to:
a.o : a.c
<cmdlist>
b.o : b.c
<cmdlist>
c.o : c.c
<cmdlist>
Extra elements on the left are disallowed except for the special case
where there are NO elements on the right (i.e. all : ). Each extra
element on the right is applied to EVERY element on the left. That is:
a.o b.o c.o : a.c b.c c.c x.h y.h
<cmdlist>
is equivalent to:
a.o : a.c x.h y.h
<cmdlist>
b.o : b.c x.h y.h
<cmdlist>
...
WILDCARDS IN SPECIFICATION
You may specify wildcards for dependancies:
*.o x.o y.o : *.c x.q y.q
<cmdlist>
equivalent to:
*.o : *.c
<cmdlist>
x.o : x.q
<cmdlist>
y.o : y.q
<cmdlist>
expanded to: (assume a.c, b.c, and c.c exist). Note that the .o's are
not scanned for, just the .c's, and then a reverse mapping is applied
to generate the .o's. For this reason, any *'s and ?'s in the right
hand side wildcard must have associated *'s and ?'s in the left hand
side wildcard.
a.o : a.c
<cmdlist>
b.o : b.c
<cmdlist>
c.o : c.c
<cmdlist>
...
When these dependancies are executed by DMake, each right hand side
wildcard will be directory-scanned for and the associated left hand
side wildcard will be GENERATED. THE LEFT HAND SIDE WILDCARD IS NOT
SEARCHED FOR BY A DIRECTORY SCAN, BUT GENERATED FROM THE RESULTS OF THE
RIGHT HAND SIDE. There are several exceptions to the general case
mentioned above:
<nonwildcard> : <wildcard> Right hand side expanded and results
all applied to the left hand side element.
all : *.c -> all : a.c b.c c.c
<wildcard> : <nonwildcard> Left hand side expanded (the only time
the left hand side is ever expanded,
and then only if there is no right hand
side in that wildcard) and the results
applied to the right hand side element.
*.c : syms -> a.c : syms, b.c : syms, c.c : syms
To be more specific, the moment some wildcard is expanded, ALL other
occurances of that wildcard will be expanded.
MACROS AND COLLECTIONS
Macros are referenced like this: $(MACNAME). Usage is straight
forward. Note that ENV: will be searched if a macro name could not
be found otherwise.
Collections are a different matter entirely. Collections are a means
of accessing the left hand side and elements in the right hand side of
dependancies at command-execution time. A collection reference is
specified with a % instead of a $. There are two predefined collection
variables called %(left) and %(right). %(left) references the left
hand side (there is always only one element on the left hand side), and
%(right) references the right hand side:
all : *.o symbols libs
Echo %(left) Echo all
Echo "%(right)" Echo "a.o b.o c.o symbols libs"
Individual wildcarded elements on the right can be referenced in the
same way:
Echo "%(*.o)" Echo "a.o b.o c.o"
Additionaly, you can specify a collection reference wildcard and if
that collection doesn't exist under that exact wildcard, the entire
right hand side collection will be searched for elements that match the
wildcard:
a.o b.o c.o : a.c b.c c.c *.h
Echo "%(right)"
cc %(*.c) -o %(left)
Results in (at execution time):
Echo "a.c x.h y.h"
cc a.c -o a.o
Echo "b.c x.h y.h"
cc b.c -o b.o
Echo "c.c x.h y.h"
cc c.c -o c.o
Unlike the ALL: line in the previous example, where *.o was an actual
collection variable, here *.c is NOT a collection variable (unless you
had specified *.o : *.c, which you didn't), so the right hand side
is searched for elements matching the wildcard.
Now pay careful attention:
SRCS = *.c
OBJS = T:*.o
all: $(OBJS)
ln %(OBJS) -o executable (ln a.o b.o c.o -o executable)
Echo "$(OBJS)" (Echo "*.o" )
Echo "%(OBJS)" (Echo "a.o b.o c.o" )
$(OBJS): $(SRCS)
cc %(right) -o %(left)
Note that $(MacName) results in the exact macro string, wildcard or not,
while %(MacName) find the macro and then finds the collection associated
with the macro's name.
MULTIPLE DEPENDANCIES W/ SAME LEFT HAND SIDE
all: *.o
ln %(*.o) -o executable
*.o : *.c
cc $(CFLAGS) %(right) -o %(left)
*.o : *.asm
as $(CFLAGS) %(right) -o %(left)
Now, recall that the right hand side wildcards are scanned for and the
left hand side generated.
*.o : *.c -> the .C's are scanned for, say, a.c b.c c.c, and
a.o b.o c.o are placed in the *.o collection
*.o : *.asm -> the .ASM's are scanned for, say, i.asm j.asm, and
i.o j.o are placed in the *.o collection
all: *.o -> The *.o's are NOT scanned for because they have already
been generated by the other two dependancies. The
collection consists of:
a.o b.o c.o i.o j.o
The fact that the left hand side is not scanned for except for the
case <wildcard> : <nonwildcard>, plus the fact that any wildcard
that is already a collection (*.o in the above example) will not be
scanned for (all : *.o in the above example) has many advantages, the
least of which is that DMake will not get confused by extra object files
in whatever directory you choose to place the objects.
VARIABLE MODIFICATION
Both macro and collection specs may be modified with a reference of
the following form:
%/$(NAME:"srcwc":"destwc")
SRCS = a.c b.c c.c -> a.c b.c c.c
OBJS = $(SRCS:"*.c":"ram:*.o") -> ram:a.o ram:b.o ram:c.o
SRCPAT = *.c
DSTPAT = ram:*.o
OBJS = $(SRCS:"$(SRCPAT)":"$(DSTPAT)") (equivalent)
SRCPAT = "*.c"
DSTPAT = "ram:*.o"
OBJS = $(SRCS:$(SRCPAT):$(DSTPAT)) (equivalent)
CONVPAT = "*.c":"ram:*.o"
OBJS = $(SRCS:$(CONVPAT)) (equivalent)
Whether you use % or $ depends on whether you want an explicit
replacement or a collection replacement. Again, refer to a
couple of examples back where we had:
all: $(OBJS) -> all: *.o
ln %(OBJS) -> ln %(*.o) -> ln a.o b.o c.o
ORDER OF EXECUTION
Execution order is based on precedence. Theoretically a Depth-First
order beginning at the leaf of each tree and then running backwards.
If you have :
all: symbols $(OBJS)
Dependancies associated with 'symbols' will be executed before those
associated with $(OBJS). Directory-Searching for wildcards in
dependancies is done in execution order as well, so you could easily
have this:
all: arced* *.o
ln %(*.o) -o ram:file
*.o : *.c
cc $(CFLAGS) %(right) -o %(left)
*.o : *.asm
as $(AFLAGS) %(right) -o %(left)
# Note here that arced* is a wildcard dummy. If we had just
# used 'arced', the 'arc' command would have been executed once
# with ALL the .arc files as arguments instead of being executed
# once for each .arc file.
arced* : *.arc
arc x %(*.arc)
In anycase, the assumption that the arc files may contain .C and .ASM
files and these will be included in the *.o : *.c and *.o : *.asm
dependancies is absolutely correct.
COMMON MISTAKES
ram:*.o ram:library.o : /dir2/*.c library.c RIGHT
cc %(right) -o %(left)
ram:*.o ram:*.o : /dir2/*.c library.c WRONG
cc %(right) -o %(left)
The dependancy labeled WRONG should be quite apparent if you break it
up manually:
ram:*.o : /dir2/*.c
<commands>
ram:*.o : library.c
<commands>
The problem is the last one ... here you are saying that ALL the object
files depend on a single source file, which is wrong.
COMMAND EXECUTION
The CD command is an internal command. Specifying CD with no arguments
returns you to the initial directory that DMake was run from. This
is incredibly useful:
OBJS = ram:*.o
SRCS = *.c
$(EXE): $(OBJS)
cd ram:
ln %(right:"ram:*":"*") -lc32 -o $(EXE)
cd
$(OBJS): $(SRCS)
cc %(right) -o %(left)
Commands are limited to ~200 chars in length (BCPL limitation) when
executed. DMake has an internal limit of 4K long command command/
dependancy lines.
There are two solutions to the problem. (1) If your object list isn't
too big you can use the CD trick to CD into the object directory and
then remove the directory prefix for the object files on the link line.
(2) You can use a shell or equivalent and have it generate a file of
the expanded names, and then use the common -f option for the linker
(link from file list).
all: $(OBJS)
shell -c "echo $(OBJS) >ram:linktmp"
ln -f ram:linktmp $(LINKLIBS) -o executable
Delete ram:linktmp
Note that in running the shell command (dillon/drew shell), I specified
$(OBJS) instead of %(OBJS) ... passed the shell the explicit wildcard
instead of the over-long collection list.